#ifndef WINGCOROUTINE_H
#define WINGCOROUTINE_H

#include "WingCoroutine_global.h"

#include <list>
#include <thread>

class WingCoroutine_p;

namespace Wing {

class WINGCOROUTINE_EXPORT WingCoroutine {
public:
  WingCoroutine(size_t stackSize);

  ~WingCoroutine();

  const std::thread::id hostThreadID() const;

  long createThread(ThreadFunctor functor, void *params = nullptr);

  bool sendCOAPC(const Wing::CO_APC &co_apc);

  bool stopThread(long id);

  bool stopAllThread();

  const ThreadInfo getThreadInfo(long id) const;

  const std::list<ThreadInfo> getAllThreads();

public:
  static void co_yeild(WingCoroutine *self);

  template <typename T>
  static void co_while(WingCoroutine *self, bool condition, T &&functor) {
    while (condition) {
      functor();
      co_yeild(self);
    }
  }

private:
  WingCoroutine_p *d_ptr;
};

} // namespace Wing

#endif // WINGCOROUTINE_H
